const assert = require('assert')

console.log("借助原型链实现代理在后设计")



const handler = {
    get(target, key, context) {
        // 这里如果访问 context 的话，就会无限递归
        console.log("要获取的属性", key, "并不存在，现在被代理拦截")
        if (target[key]) {
            return target[key]
        }
        console.log("代理中也没有你想要的", key, "准备给你返回一个默认值")
        return "默认值"
    },
    set(target, key, value) {
        console.log("想要设置的属性", key, "并不存在，现在在代理中假装帮你设置成功了")
        target[key] = value
    }
}

const person = {
    name: '罗俊华'
}

const target = {}
const emptyProxy = new Proxy(target, handler)
// 读取、写入 属性的时候优先访问 person 对象
// 如果 person 对象中找不到这个属性、方法时，会通过原型链委托给 emptyProxy 对象
// 这样一来就做到了，先访问 '被代理对象'，被代理对象中找不到的话再去 代理对象中进行处理
const afterProxy = Object.setPrototypeOf(person, emptyProxy)

console.log(afterProxy.name)
afterProxy.name = "其他人"
console.log(afterProxy.name)


afterProxy.age = 20

console.log(afterProxy.age)

// 可见，age = 20 这个属性是被存储到了 target 这个对象中
assert.equal(target.age, 20)

// 可见，person 对象还是和原来一样，只有唯一的一个 name 属性
assert.deepEqual(Object.getOwnPropertyNames(person), ['name'])